<?php
/**
 * 订单明细列表
 * User: bgl
 * Date: 2022/8/25
 * Time: 17:21
 */

namespace App\Admin\Controllers\CustomerDelivery;

use App\Admin\Extensions\Grid\Tool\Export;
use App\Models\Basics\SysPlatAccount;
use App\Admin\Actions\CustomerDelivery\ExportLogistics;
use App\Models\Basics\SysArea;
use App\Models\Basics\SysCountry;
use App\Models\Basics\SysPlat;
use App\Models\CustomerDelivery\CustomerDelivery;
use App\Models\CustomerDelivery\CustomerDeliveryDetail;
use App\Models\CustomerDelivery\CustomerOrder;
use App\Models\CustomerDelivery\CustomerOrderDetails;
use App\Models\OverSeasBa\Warehouse;
use App\Models\Product\ProductClassify;
use App\Models\Product\ProductPacking;
use App\Util\RExcel;
use App\Util\User;
use Encore\Admin\Admin;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Grid;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Str;

class CustomerOrderDetailController extends AdminController
{

    protected $title = '订单发货明细';

    protected function grid(){

        $grid = new Grid(new CustomerDeliveryDetail());
        $grid->model()->orderBy('id', 'DESC');

        $grid->column('delivery_no', '发货单号');
        $grid->column('order_no', '原始订单号');
        $grid->column('delivery_order_no', '实际发货订单号');
        $grid->column('delivery.delivery_type', '发货方式')->display(function ($value){
            return $value ? CustomerDelivery::$_deliveryType[$value] : '';
        });
        $grid->column('sku.psku_code', 'SKU');
        $grid->column('sku.psku_cn', '产品名称');
        $grid->column('skuClassify.season','季节性')->using(ProductClassify::$_season);
        $grid->column('skuClassify.title','品类');
        $grid->column('status', '发货状态')->display(function ($value){
            return $value ? CustomerDelivery::$_status[$value] : '';
        });
        $grid->column('delivery.delivered_at', '发货时间');
        $grid->column('order_detail.status', '发货申请状态')->display(function ($value){
            return $value ? CustomerOrderDetails::$_status[$value] : '';
        });
        $grid->column('order_detail.order_num', '订单数量');
        $grid->column('apply_num', '申请发货数量');
        $grid->column('ship_num', '实际发货数量');
        $grid->column('account_id', '发货账号')->display(function ($value){
            return SysPlatAccount::getAccountById($value) ?? '';
        });
        $grid->column('warehouse_id', '海外仓仓库')->display(function ($value){
            return Warehouse::getCodeById($value) ?? '';
        });
        $grid->column('delivery.area_id', '发货站点')->display(function ($value){
            return SysArea::getSysAreaById($value) ?? '';
        });
        $grid->column('delivery.country_id', '发货国家')->display(function ($value){
            return SysCountry::getCountryById($value) ?? '';
        });
        $grid->column('apply_remarks', '申请备注');
        $grid->column('delivery_remarks', '发货备注');
        $grid->column('order.plat_id', '订单平台')->display(function ($value){
            return SysPlat::getSysPlatTitle($value) ?? '';
        });
        $grid->column('delivery.seller_id', '销售人员')->display(function ($value){
            return User::getUsernameById($value) ?? '';
        });

        $grid->column('seller_sku', '平台SKU');
        $grid->column('delivery.order_at', '订单日期');
        $grid->column('sync_status', '物流同步')->display(function ($value){
            return CustomerDeliveryDetail::$_syncStatus[$value] ?? '';
        });
        $grid->column('tracking_no', '物流单号')->display(function($value){
            if($value && Str::contains($value, '佐川小包-E')){
                $value = str_ireplace('佐川小包-E ', '', $value);
            }
            return $value;
        });
        $grid->column('logistics_type', '运输方式')->display(function($value){
            $trackingNo = $this->tracking_no ?: '';
            if($trackingNo && (!$value)){
                if(Str::contains($trackingNo, '佐川小包-E')){
                    $value = '佐川急便';
                }
            }
            return $value;
        });

        $grid->column('order.order_channel', '订单渠道')->display(function ($value){
            return CustomerOrder::$_shipOrderChannel[$value] ?? '';
        });
        $grid->column('order.order_type', '订单类型')->display(function ($value){
            return  CustomerOrder::$_shipOrderType[$value] ?? '';
        });

        $grid->disableExport();
        $grid->tools(function (Grid\Tools $tools){
            $tools->append(new Export('customer-delivery/customer-order-detail-download'));
            $tools->append(new ExportLogistics('customer-delivery/customer-order-detail-logistics-download'));
        });
        $grid->disableActions();
        $grid->disableCreateButton();
        $grid->disableRowSelector();
        $grid->fixColumns(3,0);
        $grid->paginate(10);
        $grid->filter(function($filter){
            $filter->column(1/3, function ($filter) {

                $filter->where(function ($query) {
                    $query->where('delivery_no', 'like', "%{$this->input}%")
                        ->orWhere('order_no', 'like', "%{$this->input}%");
                }, '单号','no8')->placeholder('模糊查询发货号、订单号');

                $filter->where(function ($query) {
                    $query->whereHas('sku', function ($query) {
                        $query->where('psku_code', 'like', "%{$this->input}%")
                            ->orWhere('psku_cn', 'like', "%{$this->input}%");
                    });
                }, 'SKU','sku8')->placeholder('模糊查询SKU、名称');

                $filter->where(function ($query) {
                    $query->where('seller_sku', 'like', "%{$this->input}%");
                }, '平台SKU','sku18')->placeholder('模糊查询平台SKU');

                $filter->equal('sku.classify_id', '品类')->select(ProductClassify::options());
                $filter->equal('skuClassify.season', '季节性')->select(ProductClassify::$_season);
            });
           $filter->column(1/3, function ($filter){
               $filter->between('delivery.delivered_at','发货时间')->datetime();
               $filter->equal('delivery.delivery_type', '发货方式')->select(CustomerDelivery::$_deliveryType);
               $filter->equal('delivery.area_id', '发货站点')->select(SysArea::options());
               $filter->equal('status', '发货状态')->select(CustomerDeliveryDetail::$_status);
               $filter->equal('account_id', '发货账号')->select(SysPlatAccount::options());
           });
            $filter->column(1/3, function ($filter){
                $filter->equal('order.plat_id', '订单平台')->select(SysPlat::options());
                $filter->equal('order.order_channel', '订单渠道')->select(CustomerOrder::$_shipOrderChannel);
                $filter->equal('order.order_type', '订单类型')->select(CustomerOrder::$_shipOrderType);
                $filter->equal('delivery.seller_id', '销售人员')->select(User::getSellerOptions());
                $filter->equal('sync_status', '物流同步')->select(CustomerDeliveryDetail::$_syncStatus);
            });
        });

        return $grid;

    }

    private function _initQuery($filters){
        //发货单信息
        $query = CustomerDeliveryDetail::query()->orderBy('id', 'DESC');

        foreach ($filters as $key => $_filter){
            if($key == 'sku8'){
                $query->whereHas('sku', function ($query) use($_filter){
                    $query->where('psku_code', 'like', "%{$_filter}%")
                        ->orWhere('psku_cn', 'like', "%{$_filter}%");
                });
            }
            if($key == 'no8'){
                $query->where(function ($query) use($_filter){
                    $query->where('delivery_no', 'like', "%{$_filter}%")
                        ->orWhere('order_no', 'like', "%{$_filter}%");
                });
            }
            if($key == 'no18'){
                $query->where(function ($query) use($_filter){
                    $query->where('seller_sku', 'like', "%{$_filter}%");
                });
            }
            if($key == 'delivery'){ //发货单
                $query->whereHas('delivery', function ($query) use($_filter){
                    foreach ($_filter as $field => $filter){
                        if($field == 'delivered_at'){
                            if(isset($filter['start'])&&$filter['start']){
                                $query->where($field,'>=',$filter['start'] . ' 00:00:00');
                            }
                            if(isset($filter['end'])&&$filter['end']){
                                $query->where($field,'<=',$filter['end'] . ' 23:59:59');
                            }
                        }else{
                            $query->where($field, $filter);
                        }
                    }
                });
            }
            if($key == 'sku'){ //sku
                $query->whereHas('sku', function ($query) use($_filter){
                    $query->where('classify_id', $_filter['classify_id']);
                });
            }
            if($key == 'skuClassify'){ //sku品类
                $query->whereHas('skuClassify', function ($query) use($_filter){
                    $query->where('season', $_filter['season']);
                });
            }
            if($key == 'order'){ //用户订单
                $query->whereHas('order', function ($query) use($_filter){
                    $query->where('plat_id', $_filter);
                });
            }

            if(in_array($key, ['account_id', 'seller_sku', 'status','sync_status'])){
                $query->where($key,$_filter);
            }
        }
        return $query;
    }

    public function download(){
        $request = Request::input();
        $query = $this->_initQuery($request);
        $this->_exeDownload($query);
    }

    private function _exeDownload($query){
        $head = ['发货号', '订单号', '发货方式','SKU ID', 'SKU', 'SKU名称', '收货国家', '收货人', '地址', '州', '城市', '邮编', '电话',
            '发货状态', '发货时间', '申请发货状态', '下单数量', '申请发货数量', '实际发货数量', '发货账号', '海外仓仓库', '站点', '发货国家',
            '申请备注', '发货备注', '订单平台', '发货销售', '订单日期', '平台SKU', '物流同步','物流单号', '运输方式','物流重量','物流运费','物流其他费用','(系统)该单平均物流费','(系统)该单产品发货重量','(系统)该单产品物流费'];
        RExcel::exportCsv('用户发货明细订单', function () use ($head, $query) {
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            $query->chunk(1000, function ($re) use ($fp){
                $data = self::__getData($re);
                foreach ($data as $item) {
                    fputcsv($fp, $item);
                }
            });
        });
    }

    private function __getData($re){
        $weight = [];
        foreach ($re as $row){
            if(!array_key_exists($row->psku_id,$weight)){
                $weight[$row->psku_id] = ProductPacking::getShipWeight($row->psku_id);
            }
            $temp = [];
            $temp['delivery_no'] = $row->delivery_no ?? '';
            $temp['order_no'] = $row->order_no ?? '';
            $temp['delivery_type'] = CustomerDelivery::$_deliveryType[$row->delivery->delivery_type] ?? '';
            $temp['psku_id'] = $row->psku_id;
            $temp['psku_code'] = $row->sku->psku_code ?? '';
            $temp['psku_cn'] = $row->sku->psku_cn ?? '';
            $temp['country'] = $row->receiver->country ?? '';
            $temp['receiver'] = $row->receiver->receiver ?? '';
            $temp['address'] = $row->receiver->address ?? '';
            $temp['state'] = $row->receiver->state ?? '';
            $temp['city'] = $row->receiver->city ?? '';
            $temp['postcode'] = $row->receiver->postcode ?? '';
            $temp['phone'] = $row->receiver->phone ?? '';
            $temp['delivery_status'] = CustomerDeliveryDetail::$_status[$row->delivery->status] ?? '';
            $temp['delivered_at'] = $row->delivery->delivered_at ?? '';
            $temp['apply_status'] = CustomerOrderDetails::$_status[$row->order_detail->status] ?? '';
            $temp['order_num'] = $row->order_detail->order_num ?? '';
            $temp['apply_num'] = $row->apply_num ?? '';
            $temp['ship_num'] = $row->ship_num ?? '';
            $temp['account_id'] = SysPlatAccount::getAccountById($row->account_id) ?? '';
            $temp['warehouse_id'] = Warehouse::getCodeById($row->warehouse_id) ?? '';
            $temp['area_id'] = SysArea::getSysAreaById($row->delivery->area_id) ?? '';
            $temp['country_id'] = SysCountry::getCountryById($row->delivery->country_id) ?? '';
            $temp['apply_remarks'] = $row->apply_remarks ?? '';
            $temp['delivery_remarks'] = $row->delivery_remarks ?? '';
            $temp['plat_id'] = SysPlat::getSysPlatTitle($row->order->plat_id);
            $temp['seller_id'] = User::getUsernameById($row->delivery->seller_id) ?? '';
            $temp['order_at'] = $row->order->order_at ?? '';
            $temp['seller_sku'] = $row->seller_sku ?? '';
            $temp['sync_status'] = CustomerDeliveryDetail::$_syncStatus[$row->sync_status] ?? '';
            $temp['tracking_no'] = $row->tracking_no ?? '';
            $temp['logistics_type'] = $row->logistics_type ?? '';
            $temp['total_weight'] = $row->delivery->logistics->total_weight ?? '';
            $temp['shipping_fee'] = $row->delivery->logistics->shipping_fee ?? '';
            $temp['other_fee'] = $row->delivery->logistics->other_fee ?? '';
            $temp['avg_price'] = $row->delivery->avg_price ?? '';
            $temp['weight'] = $weight[$row->psku_id];
            $temp['logistics_fee'] = $row->logistics_fee;
            yield $temp;
        }
    }

    public function downloadLogistics(){
        $request = Request::input();
        $query = $this->_initQuery($request);
        $this->_exeDownloadLogistics($query);
    }

    private function _exeDownloadLogistics($query){
        $head = ['注文番号', '送付先ID', '発送明細ID', 'お荷物伝票番号', '配送会社', '発送日'];
        RExcel::exportCsv('物流信息-乐天', function () use ($head, $query) {
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            $query->chunk(1000, function ($re) use ($fp){
                $data = self::__getDataLogistics($re);
                foreach ($data as $item) {
                    fputcsv($fp, $item);
                }
            });
        });
    }

    private function __getDataLogistics($re){
        foreach ($re as $row){
            $trackingNo = $row->tracking_no ?? '';
            $logisticsType = $row->logistics_type ?? '';
            if($trackingNo && (!$logisticsType)){
                if(Str::contains($trackingNo, '佐川小包-E')){
                    $logisticsType = '佐川急便';
                }
            }
            if($trackingNo && Str::contains($trackingNo, '佐川小包-E')){
                $trackingNo = str_ireplace('佐川小包-E ', '', $trackingNo);
            }
            $temp = [
                $row->order_no ?? '',
                '',
                '',
                $trackingNo,
                $logisticsType,
                $row->delivery->delivered_at ?? ''
            ];
            yield $temp;
        }
    }
}
